package com.moneycollect.webspider.common;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.util.TimeZone;

/**
 * @author xuhuiqian
 * @since 2021/11/30 9:27
 */
public class JsonUtil {
    private static final ObjectMapper objectMapper = getMCDefaultObjectMapper();

    public static String toJson(Object object) {
        try {
            if (object == null) {
                return null;
            }

            return objectMapper.writeValueAsString(object);

        } catch (Exception e) {
            throw new RuntimeException("对象转JSON出错", e);
        }
    }

    public static <T> T parseObject(String json, Class<T> clazz) {
        try {
            if (json == null) {
                return null;
            }
            return objectMapper.readValue(json, clazz);
        } catch (Exception e) {
            throw new RuntimeException("JSON转对象出错：" + json, e);
        }
    }

    public static <T> T parseObject(String json, JavaType type) {
        try {
            if (json == null) {
                return null;
            }
            return objectMapper.readValue(json, type);
        } catch (Exception e) {
            throw new RuntimeException("JSON转对象出错：" + json, e);
        }
    }

    /**
     * @param typeRef 如: new MyTypeReference&lt;CommonRS&lt;List&lt;User&gt;&gt;&gt;(){};
     */
    //如: new TypeReference<CommonRS<List<User>>>(){};
    public static <T> T parseObject(String json, TypeReference<T> typeRef) {
        try {
            if (json == null) {
                return null;
            }
            return objectMapper.readValue(json, typeRef);
        } catch (Exception e) {
            throw new RuntimeException("JSON转对象出错：" + json, e);
        }
    }

    private static ObjectMapper getMCDefaultObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule simpleModule = new SimpleModule();
        JavaTimeModule javaTimeModule = new JavaTimeModule();

        setCommonSetting(mapper, simpleModule, javaTimeModule);

        //simpleModule.addSerializer(Date.class, new MCDateTimezone8Serializer(Date.class));
        //simpleModule.addSerializer(LocalDateTime.class, new MCLocalDateTimeTimezone8Serializer());

        //javaTimeModule.addSerializer(Date.class, new MCDateTimezone8Serializer(Date.class));
        //javaTimeModule.addSerializer(LocalDateTime.class, new MCLocalDateTimeTimezone8Serializer());

        mapper.registerModule(simpleModule);
        mapper.registerModule(javaTimeModule);

        return mapper;
    }

    private static void setCommonSetting(ObjectMapper mapper, SimpleModule simpleModule, JavaTimeModule javaTimeModule) {
        // 忽略未知属性
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 不区分大小写，防止前端写错大小写
        mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
        mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, true);

        // 序列化：不要把日期时间序列为 整数
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

        //日期格式默认时区
        mapper.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));

        //Long类型转String类型
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        //simpleModule.addSerializer(LocalDate.class, new LocalDateSerializer(Constants.DATE_FORMATTER));
        //simpleModule.addSerializer(LocalTime.class, new LocalTimeSerializer(Constants.LOCAL_TIME_FORMATTER_3));
        // Form 格式的数据反序列化时是从 这里拿的转换类
        //simpleModule.addDeserializer(Date.class, new MCDateDeserializer(Date.class));
        //simpleModule.addDeserializer(LocalDateTime.class, new MCLocalDateTimeDeserializer(Constants.DATE_MIL_TIME_FORMAT_0));
        //simpleModule.addDeserializer(LocalDate.class, new MCLocalDateDeserializer(Constants.DATE_FORMATTER));
        //simpleModule.addDeserializer(LocalTime.class, new MCLocalTimeDeserializer(Constants.LOCAL_TIME_FORMATTER_3));


        //javaTimeModule.addDeserializer(Date.class, new MCDateDeserializer(Date.class));
        //javaTimeModule.addDeserializer(LocalDateTime.class, new MCLocalDateTimeDeserializer(Constants.DATE_MIL_TIME_FORMAT_0));
        //javaTimeModule.addDeserializer(LocalDate.class, new MCLocalDateDeserializer(Constants.DATE_FORMATTER));
        //javaTimeModule.addDeserializer(LocalTime.class, new MCLocalTimeDeserializer(Constants.LOCAL_TIME_FORMATTER_3));
        //javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(Constants.DATE_FORMATTER));
        //javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(Constants.LOCAL_TIME_FORMATTER_3));
    }
}
